import { Tree } from '@angular-devkit/schematics';
import {
  SchematicTestRunner,
  UnitTestTree,
} from '@angular-devkit/schematics/testing';
import * as path from 'node:path';
import { beforeEach, describe, expect, it } from 'vitest';
import { readJsonInTree } from '../../src/utils';

const schematicRunner = new SchematicTestRunner(
  '@angular-eslint/schematics',
  path.join(__dirname, '../../dist/collection.json'),
);

const rootProjectName = 'root-project';
const legacyProjectName = 'legacy-project';
const otherProjectName = 'other-project';

describe('add-eslint-to-project', () => {
  describe('eslint v8 and .eslintrc.json', () => {
    let appTree: UnitTestTree;

    beforeEach(() => {
      appTree = new UnitTestTree(Tree.empty());
      appTree.create(
        'package.json',
        JSON.stringify({
          devDependencies: {
            // Pre v9 version of ESLint
            eslint: '8.0.0',
          },
        }),
      );
      appTree.create(
        'angular.json',
        JSON.stringify({
          $schema: './node_modules/@angular/cli/lib/config/schema.json',
          version: 1,
          newProjectRoot: 'projects',
          projects: {
            [rootProjectName]: {
              projectType: 'application',
              schematics: {},
              root: '',
              sourceRoot: 'src',
              prefix: 'app',
              architect: {
                build: {},
                serve: {},
                'extract-i18n': {},
                test: {},
                lint: {},
              },
            },
            [legacyProjectName]: {
              projectType: 'application',
              schematics: {},
              root: `projects/${legacyProjectName}`,
              sourceRoot: `projects/${legacyProjectName}/src`,
              prefix: 'app',
              architect: {
                build: {},
                serve: {},
                'extract-i18n': {},
                test: {},
                lint: {},
                e2e: {},
              },
            },
            [otherProjectName]: {
              projectType: 'application',
              schematics: {},
              root: `projects/${otherProjectName}`,
              sourceRoot: `projects/${otherProjectName}/src`,
              prefix: 'app',
              architect: {
                build: {},
                serve: {},
                'extract-i18n': {},
                test: {},
                lint: {},
              },
            },
          },
        }),
      );
    });

    it('should add ESLint to the standard Angular CLI root project which it generates by default', async () => {
      const options = {
        project: rootProjectName,
      };

      await schematicRunner.runSchematic(
        'add-eslint-to-project',
        options,
        appTree,
      );

      expect(
        readJsonInTree(appTree, 'angular.json').projects[rootProjectName]
          .architect.lint,
      ).toMatchInlineSnapshot(`
        {
          "builder": "@angular-eslint/builder:lint",
          "options": {
            "lintFilePatterns": [
              "src/**/*.ts",
              "src/**/*.html",
            ],
          },
        }
      `);

      expect(readJsonInTree(appTree, '.eslintrc.json')).toMatchInlineSnapshot(`
        {
          "ignorePatterns": [
            "projects/**/*",
          ],
          "overrides": [
            {
              "extends": [
                "eslint:recommended",
                "plugin:@typescript-eslint/recommended",
                "plugin:@angular-eslint/recommended",
                "plugin:@angular-eslint/template/process-inline-templates",
              ],
              "files": [
                "*.ts",
              ],
              "rules": {
                "@angular-eslint/component-selector": [
                  "error",
                  {
                    "prefix": "app",
                    "style": "kebab-case",
                    "type": "element",
                  },
                ],
                "@angular-eslint/directive-selector": [
                  "error",
                  {
                    "prefix": "app",
                    "style": "camelCase",
                    "type": "attribute",
                  },
                ],
              },
            },
            {
              "extends": [
                "plugin:@angular-eslint/template/recommended",
                "plugin:@angular-eslint/template/accessibility",
              ],
              "files": [
                "*.html",
              ],
              "rules": {},
            },
          ],
          "root": true,
        }
      `);
    });

    it('should add ESLint to the legacy Angular CLI projects which are generated with e2e after the workspace already exists', async () => {
      const options = {
        project: legacyProjectName,
      };

      await schematicRunner.runSchematic(
        'add-eslint-to-project',
        options,
        appTree,
      );

      const projectConfig = readJsonInTree(appTree, 'angular.json').projects[
        legacyProjectName
      ];

      expect(projectConfig.architect.lint).toMatchInlineSnapshot(`
        {
          "builder": "@angular-eslint/builder:lint",
          "options": {
            "lintFilePatterns": [
              "projects/legacy-project/**/*.ts",
              "projects/legacy-project/**/*.html",
            ],
          },
        }
      `);

      expect(readJsonInTree(appTree, `${projectConfig.root}/.eslintrc.json`))
        .toMatchInlineSnapshot(`
          {
            "extends": "../../.eslintrc.json",
            "ignorePatterns": [
              "!**/*",
            ],
            "overrides": [
              {
                "files": [
                  "*.ts",
                ],
                "rules": {
                  "@angular-eslint/component-selector": [
                    "error",
                    {
                      "prefix": "app",
                      "style": "kebab-case",
                      "type": "element",
                    },
                  ],
                  "@angular-eslint/directive-selector": [
                    "error",
                    {
                      "prefix": "app",
                      "style": "camelCase",
                      "type": "attribute",
                    },
                  ],
                },
              },
              {
                "files": [
                  "*.html",
                ],
                "rules": {},
              },
            ],
          }
        `);
    });

    it('should add ESLint to the any other Angular CLI projects which are generated after the workspace already exists', async () => {
      const options = {
        project: otherProjectName,
      };

      await schematicRunner.runSchematic(
        'add-eslint-to-project',
        options,
        appTree,
      );

      const projectConfig = readJsonInTree(appTree, 'angular.json').projects[
        otherProjectName
      ];

      expect(projectConfig.architect.lint).toMatchInlineSnapshot(`
        {
          "builder": "@angular-eslint/builder:lint",
          "options": {
            "lintFilePatterns": [
              "projects/other-project/**/*.ts",
              "projects/other-project/**/*.html",
            ],
          },
        }
      `);

      expect(readJsonInTree(appTree, `${projectConfig.root}/.eslintrc.json`))
        .toMatchInlineSnapshot(`
          {
            "extends": "../../.eslintrc.json",
            "ignorePatterns": [
              "!**/*",
            ],
            "overrides": [
              {
                "files": [
                  "*.ts",
                ],
                "rules": {
                  "@angular-eslint/component-selector": [
                    "error",
                    {
                      "prefix": "app",
                      "style": "kebab-case",
                      "type": "element",
                    },
                  ],
                  "@angular-eslint/directive-selector": [
                    "error",
                    {
                      "prefix": "app",
                      "style": "camelCase",
                      "type": "attribute",
                    },
                  ],
                },
              },
              {
                "files": [
                  "*.html",
                ],
                "rules": {},
              },
            ],
          }
        `);
    });

    describe('--setParserOptionsProject=true', () => {
      it('should add ESLint to the legacy Angular CLI projects which are generated with e2e after the workspace already exists', async () => {
        const options = {
          project: legacyProjectName,
          setParserOptionsProject: true,
        };

        await schematicRunner.runSchematic(
          'add-eslint-to-project',
          options,
          appTree,
        );

        const projectConfig = readJsonInTree(appTree, 'angular.json').projects[
          legacyProjectName
        ];

        expect(projectConfig.architect.lint).toMatchInlineSnapshot(`
          {
            "builder": "@angular-eslint/builder:lint",
            "options": {
              "lintFilePatterns": [
                "projects/legacy-project/**/*.ts",
                "projects/legacy-project/**/*.html",
              ],
            },
          }
        `);

        expect(readJsonInTree(appTree, `${projectConfig.root}/.eslintrc.json`))
          .toMatchInlineSnapshot(`
            {
              "extends": "../../.eslintrc.json",
              "ignorePatterns": [
                "!**/*",
              ],
              "overrides": [
                {
                  "files": [
                    "*.ts",
                  ],
                  "parserOptions": {
                    "project": [
                      "projects/legacy-project/tsconfig.(app|spec).json",
                      "projects/legacy-project/e2e/tsconfig.json",
                    ],
                  },
                  "rules": {
                    "@angular-eslint/component-selector": [
                      "error",
                      {
                        "prefix": "app",
                        "style": "kebab-case",
                        "type": "element",
                      },
                    ],
                    "@angular-eslint/directive-selector": [
                      "error",
                      {
                        "prefix": "app",
                        "style": "camelCase",
                        "type": "attribute",
                      },
                    ],
                  },
                },
                {
                  "files": [
                    "*.html",
                  ],
                  "rules": {},
                },
              ],
            }
          `);
      });

      it('should add ESLint to the any other Angular CLI projects which are generated after the workspace already exists', async () => {
        const options = {
          project: otherProjectName,
          setParserOptionsProject: true,
        };

        await schematicRunner.runSchematic(
          'add-eslint-to-project',
          options,
          appTree,
        );

        const projectConfig = readJsonInTree(appTree, 'angular.json').projects[
          otherProjectName
        ];

        expect(projectConfig.architect.lint).toMatchInlineSnapshot(`
          {
            "builder": "@angular-eslint/builder:lint",
            "options": {
              "lintFilePatterns": [
                "projects/other-project/**/*.ts",
                "projects/other-project/**/*.html",
              ],
            },
          }
        `);

        expect(readJsonInTree(appTree, `${projectConfig.root}/.eslintrc.json`))
          .toMatchInlineSnapshot(`
            {
              "extends": "../../.eslintrc.json",
              "ignorePatterns": [
                "!**/*",
              ],
              "overrides": [
                {
                  "files": [
                    "*.ts",
                  ],
                  "parserOptions": {
                    "project": [
                      "projects/other-project/tsconfig.(app|spec).json",
                    ],
                  },
                  "rules": {
                    "@angular-eslint/component-selector": [
                      "error",
                      {
                        "prefix": "app",
                        "style": "kebab-case",
                        "type": "element",
                      },
                    ],
                    "@angular-eslint/directive-selector": [
                      "error",
                      {
                        "prefix": "app",
                        "style": "camelCase",
                        "type": "attribute",
                      },
                    ],
                  },
                },
                {
                  "files": [
                    "*.html",
                  ],
                  "rules": {},
                },
              ],
            }
          `);
      });
    });

    describe('custom root project sourceRoot', () => {
      let tree2: UnitTestTree;

      beforeEach(() => {
        tree2 = new UnitTestTree(Tree.empty());
        tree2.create(
          'package.json',
          JSON.stringify({
            devDependencies: {
              // Pre v9 version of ESLint
              eslint: '8.0.0',
            },
          }),
        );
        tree2.create(
          'angular.json',
          JSON.stringify({
            $schema: './node_modules/@angular/cli/lib/config/schema.json',
            version: 1,
            newProjectRoot: 'projects',
            projects: {
              [rootProjectName]: {
                projectType: 'application',
                schematics: {},
                root: '',
                sourceRoot: 'custom-source-root',
                prefix: 'app',
                architect: {
                  build: {},
                  serve: {},
                  'extract-i18n': {},
                  test: {},
                  lint: {},
                },
              },
              [legacyProjectName]: {
                projectType: 'application',
                schematics: {},
                root: `projects/${legacyProjectName}`,
                sourceRoot: `projects/${legacyProjectName}/src`,
                prefix: 'app',
                architect: {
                  build: {},
                  serve: {},
                  'extract-i18n': {},
                  test: {},
                  lint: {},
                  e2e: {},
                },
              },
              [otherProjectName]: {
                projectType: 'application',
                schematics: {},
                root: `projects/${otherProjectName}`,
                sourceRoot: `projects/${otherProjectName}/src`,
                prefix: 'app',
                architect: {
                  build: {},
                  serve: {},
                  'extract-i18n': {},
                  test: {},
                  lint: {},
                },
              },
            },
          }),
        );
      });

      it('should correctly add ESLint to the Angular CLI root project even when it has a custom sourceRoot', async () => {
        const options = {
          project: rootProjectName,
        };

        await schematicRunner.runSchematic(
          'add-eslint-to-project',
          options,
          tree2,
        );

        expect(
          readJsonInTree(tree2, 'angular.json').projects[rootProjectName]
            .architect.lint,
        ).toMatchInlineSnapshot(`
          {
            "builder": "@angular-eslint/builder:lint",
            "options": {
              "lintFilePatterns": [
                "custom-source-root/**/*.ts",
                "custom-source-root/**/*.html",
              ],
            },
          }
        `);

        expect(readJsonInTree(tree2, '.eslintrc.json')).toMatchInlineSnapshot(`
          {
            "ignorePatterns": [
              "projects/**/*",
            ],
            "overrides": [
              {
                "extends": [
                  "eslint:recommended",
                  "plugin:@typescript-eslint/recommended",
                  "plugin:@angular-eslint/recommended",
                  "plugin:@angular-eslint/template/process-inline-templates",
                ],
                "files": [
                  "*.ts",
                ],
                "rules": {
                  "@angular-eslint/component-selector": [
                    "error",
                    {
                      "prefix": "app",
                      "style": "kebab-case",
                      "type": "element",
                    },
                  ],
                  "@angular-eslint/directive-selector": [
                    "error",
                    {
                      "prefix": "app",
                      "style": "camelCase",
                      "type": "attribute",
                    },
                  ],
                },
              },
              {
                "extends": [
                  "plugin:@angular-eslint/template/recommended",
                  "plugin:@angular-eslint/template/accessibility",
                ],
                "files": [
                  "*.html",
                ],
                "rules": {},
              },
            ],
            "root": true,
          }
        `);
      });
    });
  });

  describe('eslint v9 and flat config', () => {
    let appTree: UnitTestTree;

    beforeEach(() => {
      appTree = new UnitTestTree(Tree.empty());
      appTree.create('package.json', JSON.stringify({}));
      appTree.create(
        'angular.json',
        JSON.stringify({
          $schema: './node_modules/@angular/cli/lib/config/schema.json',
          version: 1,
          newProjectRoot: 'projects',
          projects: {
            [rootProjectName]: {
              projectType: 'application',
              schematics: {},
              root: '',
              sourceRoot: 'src',
              prefix: 'app',
              architect: {
                build: {},
                serve: {},
                'extract-i18n': {},
                test: {},
                lint: {},
              },
            },
            [legacyProjectName]: {
              projectType: 'application',
              schematics: {},
              root: `projects/${legacyProjectName}`,
              sourceRoot: `projects/${legacyProjectName}/src`,
              prefix: 'app',
              architect: {
                build: {},
                serve: {},
                'extract-i18n': {},
                test: {},
                lint: {},
                e2e: {},
              },
            },
            [otherProjectName]: {
              projectType: 'application',
              schematics: {},
              root: `projects/${otherProjectName}`,
              sourceRoot: `projects/${otherProjectName}/src`,
              prefix: 'app',
              architect: {
                build: {},
                serve: {},
                'extract-i18n': {},
                test: {},
                lint: {},
              },
            },
          },
        }),
      );
    });

    it('should add ESLint to the standard Angular CLI root project which it generates by default', async () => {
      const options = {
        project: rootProjectName,
      };

      await schematicRunner.runSchematic(
        'add-eslint-to-project',
        options,
        appTree,
      );

      expect(
        readJsonInTree(appTree, 'angular.json').projects[rootProjectName]
          .architect.lint,
      ).toMatchInlineSnapshot(`
        {
          "builder": "@angular-eslint/builder:lint",
          "options": {
            "lintFilePatterns": [
              "src/**/*.ts",
              "src/**/*.html",
            ],
          },
        }
      `);

      expect(appTree.read('eslint.config.js')?.toString())
        .toMatchInlineSnapshot(`
          "// @ts-check
          const eslint = require("@eslint/js");
          const { defineConfig } = require("eslint/config");
          const tseslint = require("typescript-eslint");
          const angular = require("angular-eslint");

          module.exports = defineConfig([
            {
              files: ["**/*.ts"],
              extends: [
                eslint.configs.recommended,
                tseslint.configs.recommended,
                tseslint.configs.stylistic,
                angular.configs.tsRecommended,
              ],
              processor: angular.processInlineTemplates,
              rules: {
                "@angular-eslint/directive-selector": [
                  "error",
                  {
                    type: "attribute",
                    prefix: "app",
                    style: "camelCase",
                  },
                ],
                "@angular-eslint/component-selector": [
                  "error",
                  {
                    type: "element",
                    prefix: "app",
                    style: "kebab-case",
                  },
                ],
              },
            },
            {
              files: ["**/*.html"],
              extends: [
                angular.configs.templateRecommended,
                angular.configs.templateAccessibility,
              ],
              rules: {},
            }
          ]);
          "
        `);
    });

    it('should add ESLint to the legacy Angular CLI projects which are generated with e2e after the workspace already exists', async () => {
      const options = {
        project: legacyProjectName,
      };

      await schematicRunner.runSchematic(
        'add-eslint-to-project',
        options,
        appTree,
      );

      const projectConfig = readJsonInTree(appTree, 'angular.json').projects[
        legacyProjectName
      ];

      expect(projectConfig.architect.lint).toMatchInlineSnapshot(`
        {
          "builder": "@angular-eslint/builder:lint",
          "options": {
            "eslintConfig": "projects/legacy-project/eslint.config.js",
            "lintFilePatterns": [
              "projects/legacy-project/**/*.ts",
              "projects/legacy-project/**/*.html",
            ],
          },
        }
      `);

      expect(appTree.read(`${projectConfig.root}/eslint.config.js`)?.toString())
        .toMatchInlineSnapshot(`
          "// @ts-check
          const { defineConfig } = require("eslint/config");
          const rootConfig = require("../../eslint.config.js");

          module.exports = defineConfig([
            ...rootConfig,
            {
              files: ["**/*.ts"],
              rules: {
                "@angular-eslint/directive-selector": [
                  "error",
                  {
                    type: "attribute",
                    prefix: "app",
                    style: "camelCase",
                  },
                ],
                "@angular-eslint/component-selector": [
                  "error",
                  {
                    type: "element",
                    prefix: "app",
                    style: "kebab-case",
                  },
                ],
              },
            },
            {
              files: ["**/*.html"],
              rules: {},
            }
          ]);
          "
        `);
    });

    it('should add ESLint to the any other Angular CLI projects which are generated after the workspace already exists', async () => {
      const options = {
        project: otherProjectName,
      };

      await schematicRunner.runSchematic(
        'add-eslint-to-project',
        options,
        appTree,
      );

      const projectConfig = readJsonInTree(appTree, 'angular.json').projects[
        otherProjectName
      ];

      expect(projectConfig.architect.lint).toMatchInlineSnapshot(`
        {
          "builder": "@angular-eslint/builder:lint",
          "options": {
            "eslintConfig": "projects/other-project/eslint.config.js",
            "lintFilePatterns": [
              "projects/other-project/**/*.ts",
              "projects/other-project/**/*.html",
            ],
          },
        }
      `);

      expect(appTree.read(`${projectConfig.root}/eslint.config.js`)?.toString())
        .toMatchInlineSnapshot(`
          "// @ts-check
          const { defineConfig } = require("eslint/config");
          const rootConfig = require("../../eslint.config.js");

          module.exports = defineConfig([
            ...rootConfig,
            {
              files: ["**/*.ts"],
              rules: {
                "@angular-eslint/directive-selector": [
                  "error",
                  {
                    type: "attribute",
                    prefix: "app",
                    style: "camelCase",
                  },
                ],
                "@angular-eslint/component-selector": [
                  "error",
                  {
                    type: "element",
                    prefix: "app",
                    style: "kebab-case",
                  },
                ],
              },
            },
            {
              files: ["**/*.html"],
              rules: {},
            }
          ]);
          "
        `);
    });

    describe('--setParserOptionsProject=true', () => {
      it('should add ESLint to the legacy Angular CLI projects which are generated with e2e after the workspace already exists', async () => {
        const options = {
          project: legacyProjectName,
          setParserOptionsProject: true,
        };

        await schematicRunner.runSchematic(
          'add-eslint-to-project',
          options,
          appTree,
        );

        const projectConfig = readJsonInTree(appTree, 'angular.json').projects[
          legacyProjectName
        ];

        expect(projectConfig.architect.lint).toMatchInlineSnapshot(`
          {
            "builder": "@angular-eslint/builder:lint",
            "options": {
              "eslintConfig": "projects/legacy-project/eslint.config.js",
              "lintFilePatterns": [
                "projects/legacy-project/**/*.ts",
                "projects/legacy-project/**/*.html",
              ],
            },
          }
        `);

        expect(
          appTree.read(`${projectConfig.root}/eslint.config.js`)?.toString(),
        ).toMatchInlineSnapshot(`
          "// @ts-check
          const { defineConfig } = require("eslint/config");
          const rootConfig = require("../../eslint.config.js");

          module.exports = defineConfig([
            ...rootConfig,
            {
              files: ["**/*.ts"],
              languageOptions: {
                parserOptions: {
                  projectService: true,
                },
              },
              rules: {
                "@angular-eslint/directive-selector": [
                  "error",
                  {
                    type: "attribute",
                    prefix: "app",
                    style: "camelCase",
                  },
                ],
                "@angular-eslint/component-selector": [
                  "error",
                  {
                    type: "element",
                    prefix: "app",
                    style: "kebab-case",
                  },
                ],
              },
            },
            {
              files: ["**/*.html"],
              rules: {},
            }
          ]);
          "
        `);
      });

      it('should add ESLint to the any other Angular CLI projects which are generated after the workspace already exists', async () => {
        const options = {
          project: otherProjectName,
          setParserOptionsProject: true,
        };

        await schematicRunner.runSchematic(
          'add-eslint-to-project',
          options,
          appTree,
        );

        const projectConfig = readJsonInTree(appTree, 'angular.json').projects[
          otherProjectName
        ];

        expect(projectConfig.architect.lint).toMatchInlineSnapshot(`
          {
            "builder": "@angular-eslint/builder:lint",
            "options": {
              "eslintConfig": "projects/other-project/eslint.config.js",
              "lintFilePatterns": [
                "projects/other-project/**/*.ts",
                "projects/other-project/**/*.html",
              ],
            },
          }
        `);

        expect(
          appTree.read(`${projectConfig.root}/eslint.config.js`)?.toString(),
        ).toMatchInlineSnapshot(`
          "// @ts-check
          const { defineConfig } = require("eslint/config");
          const rootConfig = require("../../eslint.config.js");

          module.exports = defineConfig([
            ...rootConfig,
            {
              files: ["**/*.ts"],
              languageOptions: {
                parserOptions: {
                  projectService: true,
                },
              },
              rules: {
                "@angular-eslint/directive-selector": [
                  "error",
                  {
                    type: "attribute",
                    prefix: "app",
                    style: "camelCase",
                  },
                ],
                "@angular-eslint/component-selector": [
                  "error",
                  {
                    type: "element",
                    prefix: "app",
                    style: "kebab-case",
                  },
                ],
              },
            },
            {
              files: ["**/*.html"],
              rules: {},
            }
          ]);
          "
        `);
      });
    });

    describe('custom root project sourceRoot', () => {
      let tree2: UnitTestTree;

      beforeEach(() => {
        tree2 = new UnitTestTree(Tree.empty());
        tree2.create('package.json', JSON.stringify({}));
        tree2.create(
          'angular.json',
          JSON.stringify({
            $schema: './node_modules/@angular/cli/lib/config/schema.json',
            version: 1,
            newProjectRoot: 'projects',
            projects: {
              [rootProjectName]: {
                projectType: 'application',
                schematics: {},
                root: '',
                sourceRoot: 'custom-source-root',
                prefix: 'app',
                architect: {
                  build: {},
                  serve: {},
                  'extract-i18n': {},
                  test: {},
                  lint: {},
                },
              },
              [legacyProjectName]: {
                projectType: 'application',
                schematics: {},
                root: `projects/${legacyProjectName}`,
                sourceRoot: `projects/${legacyProjectName}/src`,
                prefix: 'app',
                architect: {
                  build: {},
                  serve: {},
                  'extract-i18n': {},
                  test: {},
                  lint: {},
                  e2e: {},
                },
              },
              [otherProjectName]: {
                projectType: 'application',
                schematics: {},
                root: `projects/${otherProjectName}`,
                sourceRoot: `projects/${otherProjectName}/src`,
                prefix: 'app',
                architect: {
                  build: {},
                  serve: {},
                  'extract-i18n': {},
                  test: {},
                  lint: {},
                },
              },
            },
          }),
        );
      });

      it('should correctly add ESLint to the Angular CLI root project even when it has a custom sourceRoot', async () => {
        const options = {
          project: rootProjectName,
        };

        await schematicRunner.runSchematic(
          'add-eslint-to-project',
          options,
          tree2,
        );

        expect(
          readJsonInTree(tree2, 'angular.json').projects[rootProjectName]
            .architect.lint,
        ).toMatchInlineSnapshot(`
          {
            "builder": "@angular-eslint/builder:lint",
            "options": {
              "lintFilePatterns": [
                "custom-source-root/**/*.ts",
                "custom-source-root/**/*.html",
              ],
            },
          }
        `);

        expect(tree2.read(`eslint.config.js`)?.toString())
          .toMatchInlineSnapshot(`
            "// @ts-check
            const eslint = require("@eslint/js");
            const { defineConfig } = require("eslint/config");
            const tseslint = require("typescript-eslint");
            const angular = require("angular-eslint");

            module.exports = defineConfig([
              {
                files: ["**/*.ts"],
                extends: [
                  eslint.configs.recommended,
                  tseslint.configs.recommended,
                  tseslint.configs.stylistic,
                  angular.configs.tsRecommended,
                ],
                processor: angular.processInlineTemplates,
                rules: {
                  "@angular-eslint/directive-selector": [
                    "error",
                    {
                      type: "attribute",
                      prefix: "app",
                      style: "camelCase",
                    },
                  ],
                  "@angular-eslint/component-selector": [
                    "error",
                    {
                      type: "element",
                      prefix: "app",
                      style: "kebab-case",
                    },
                  ],
                },
              },
              {
                files: ["**/*.html"],
                extends: [
                  angular.configs.templateRecommended,
                  angular.configs.templateAccessibility,
                ],
                rules: {},
              }
            ]);
            "
          `);
      });
    });
  });
});
